#ifndef __VIEW_H__
#define __VIEW_H__

#include "./uiobject.h"
#include "layout/layout.h"

namespace MiniUI
{

class View : public UIObject,
             public Creator<View>,
             public TypeObject<View>
{
public:
    friend class UIObject;
    friend class Creator<View>;
protected:
    View(const char* szType);
    View();
    virtual ~View();
public:
    void SetWinView(WinView* pWinView);
    //Child
    virtual bool AddChild(UIObject* pChild);
    virtual bool DeleteChild(UIObject* pChild);
    virtual int InsertChild(int nPos, UIObject* pChild);
    UIObject* GetFirstChild() const;
    UIObject* GetLastChild() const;
    UIObject* GetNextChild(UIObject* pChild) const;
    UIObject* GetPrevChild(UIObject* pChild) const;
    UIObject* DoHitTest(const Type::MiniPoint& pt);
    //Layout
    bool SetLayout(Layout* pLayout);
    Layout* GetLayout() const;
    virtual void DoLayout();
    bool LockLayout();
    bool UnlockLayout(bool bLayout = true);
    bool IsLockLayout();
    //Update
    bool LockUpdate();
    bool UnlockUpdate(bool bRedraw = true);
public:
    //for Render
    virtual bool RenderTo(Graphics& graphics, const Type::MiniRect& rcRender, const uint8 blendValue);
    void RenderBackground(Graphics& graphics, const Type::MiniRect& rcRender, const uint8 blendValue);
    void RenderContent(Graphics& graphics, const Type::MiniRect& rcRender, const uint8 blendValue);
protected:
    //Child Operation
    void AddObject(UIObject* pChild);
    void DeleteObject(UIObject* pChild);
    int InsertObject(int nPos, UIObject* pChild);
    //Child GetInformation
    void GetMousePosDifferToChildPos(const Type::MiniPoint& pt, UIObject* pObj, Type::MiniPoint& ptChild);
    UIObject* ChildHitTest(const Type::MiniPoint& pt);
    //Child Event
    void ChildChange(const UIObject* pChild, const Type::MiniRect& rect);
    void ChildMove(const UIObject* pChild, const Type::MiniPoint& ptSrc, const Type::MiniPoint& ptDst);
    void ChildResize(const UIObject* pChild, const Type::MiniSize& szOld, const Type::MiniSize& szNew);
    //On Mouse Event
    virtual bool Click(const Type::MiniPoint& pt, MouseButton button, uint keyState, bool& bHandled);
    virtual bool DblClk(const Type::MiniPoint& pt, MouseButton button, uint keyState, bool& bHandled);
    virtual bool MouseDown(const Type::MiniPoint& pt, MouseButton button, uint keyState, bool& bHandled);
    virtual bool MouseUp(const Type::MiniPoint& pt, MouseButton button, uint keyState, bool& bHandled);
    virtual bool MouseMove(const Type::MiniPoint& pt, uint keyState, bool& bHandled);
    virtual void MouseHover();
    virtual void MouseEnter();
    virtual void MouseLeave();
    virtual bool MouseWheel(const Type::MiniPoint& pt, uint keyState, int16 zDelta, bool& bHandled);
    //virtual void Change(const Type::MiniRect& rect);
    //virtual void Move(const Type::MiniPoint& ptSrc, const Type::MiniPoint& ptDst);
    virtual void Resize(const Type::MiniSize& szOld, const Type::MiniSize& szNew);
private:
    void Init();
protected:
    UIObject* m_pChild;
    UIObject* m_pObjMouseDown;
    UIObject* m_pObjMouseEnter;
    Layout* m_pLayout;
    uint8 m_lockLayout;
    uint8 m_lockUpdate;
    Type::MiniRect m_rcRender;
};

}

#endif